# Account UI
ident = '$Id: account_ui.py 130 2006-06-27 04:22:32Z ahmad $'
import wx, common, images
import newsletter_ui
import build_ui
import dav_ui
import binder_ui
import contact_ui
import form_ui
import gcb_ui
import content_search
import icon_manager
from xml.dom		import minidom
import wx.lib.masked as masked


# Sort BY and Find By
BY_STATUS 	= 0
BY_ID		= 1
BY_NAME		= 2

BY_ISS_ID		= 0
BY_ISS_NAME 	= 1
BY_PUB_ID		= 2
BY_PUB_NAME 	= 3

# Menu bar items
ID_SORTBY		= 101
ID_FINDBY			= 102
ID_FINDBY_TEXT	= 103
IDM_PUBLISHER		= 104
IDM_DISCONNECT		= 105
IDM_TRACER			= 106
IDM_BUILD			= 107
IDM_INSPECTOR		= 108
IDM_SCRIPT_HELPER	= 109

ID_PUB_CREATE		= 111
ID_PUB_EDIT			= 112
ID_PUB_DELETE		= 113
ID_PUB_NEW_ISS		= 114
ID_PUB_CLONE			= 115

ID_ISS_EDIT			= 121
ID_ISS_DELETE			= 122
ID_ISS_PUBLISH		= 123
ID_ISS_CLONE			= 124

class account_frame( wx.Frame ):
	def __init__( self, account_manager, title, account ):
		nb_style = wx.NB_TOP
		if wx.Platform == '__WXMAC__':
			nb_style = wx.NB_TOP
			if account.y < common.default_account_y: account.y = common.default_account_y
		window_pos	= ( account.x, account.y )
		window_size	= ( account.w, account.h )
		wx.Frame.__init__( self, None, -1, title, pos=window_pos, size=window_size )
		common.metalic( self )
		self.account= account
		self.account_manager = account_manager
		self.account.window = self
		self.build_dialog = None
		self.designated_contact_uuid = ''
		self.zoomed 	= False
		self.zooming	= False
		self.zoomedon	= 0
		# Take care of the status bar and the menu bar
		self.CreateStatusBar()
		# Create the menu bar
		self.create_menu_items()
		# Set the close event for this frame
		self.Bind( wx.EVT_CLOSE, self.OnClose )
		tID = wx.NewId()
		# The whole mess
		icon = icon_manager.get_icon( 'ESM' )
		self.SetIcon( icon )
		self.pbSplitter = wx.SplitterWindow( self, -1, style = wx.SP_LIVE_UPDATE )
		self.pbSplitter.Bind( wx.EVT_SPLITTER_SASH_POS_CHANGED, self.OnSashChanged )
		# Start the loading process
		self.account_manager.set_account_loading( account.id, 'Loading' )
		# The pubication book
		self.pbook = wx.Notebook( self.pbSplitter, -1, style=nb_style )
		self.pbook.Bind( wx.EVT_KEY_DOWN, self.OnKeyPressed )
		#load files tab
		common.set_busy_info( "Loading user files" )
		self.dav_control = dav_ui.dav_control( self.pbook, -1, self.account )
		self.pbook.AddPage( self.dav_control, "Files" )
		self.account_manager.set_account_loading( account.id, 'Loading.' )
		#load the web tab
		common.set_busy_info( "Loading the Web module" )
		self.web_control = newsletter_ui.web_control( self.pbook, -1, self.account )
		self.pbook.AddPage( self.web_control, "Web" )
		self.account_manager.set_account_loading( account.id, 'Loading..' )
		#load the newsletter tab
		common.set_busy_info( "Loading the Newsletter module" )
		self.newsletter_control = newsletter_ui.newsletter_control( self.pbook, -1, self.account )
		self.pbook.AddPage( self.newsletter_control, "News" )
		self.account_manager.set_account_loading( account.id, 'Loading...' )
		#load the email tab
		common.set_busy_info( "Loading the Email module" )
		self.email_control = newsletter_ui.email_control( self.pbook, -1, self.account )
		self.pbook.AddPage( self.email_control, "Email" )
		self.account_manager.set_account_loading( account.id, 'Loading....' )
		#load the surveys tab
		# self.survey_control = form_ui.survey_control( self.pbook, -1, self.account )
		# self.pbook.AddPage( self.survey_control, "Survey" )
		# self.account_manager.set_account_loading( account.id, 'Loading.....' )
		# #load the referrals tab
		# self.referral_control = form_ui.referral_control( self.pbook, -1, self.account )
		# self.pbook.AddPage( self.referral_control, "Referral" )
		# self.account_manager.set_account_loading( account.id, 'Loading......' )

		self.search_control = content_search.search_control( self.pbook, self.account, True )
		self.pbook.AddPage( self.search_control, "Search" )
		self.pbook.Show()
		#print "Showing"
		self.il = wx.ImageList( 16,16 )
		self.folder_w_icon = self.il.Add( images.getFolderWBitmap() )
		self.issue_w_icon = self.il.Add( images.getIssueWBitmap() )
		self.folder_n_icon = self.il.Add( images.getFolderNBitmap() )
		self.issue_n_icon = self.il.Add( images.getIssueNBitmap() )
		self.folder_e_icon = self.il.Add( images.getFolderEBitmap() )
		self.issue_e_icon = self.il.Add( images.getIssueEBitmap() )
		self.form_icon = self.il.Add( images.getFormBitmap() )
		self.survey_icon = self.il.Add( images.getSurveyBitmap() )
		self.promotion_icon = self.il.Add( images.getPromotionBitmap() )
		self.referral_icon = self.il.Add( images.getReferralBitmap() )
		self.binder_icon = self.il.Add( images.getBinderBitmap() )
		self.instance_icon = self.il.Add( images.getInstanceBitmap() )
		self.contact_icon = self.il.Add( images.getContactBitmap() )
		self.group_icon = self.il.Add( images.getGroupBitmap() )
		# The binder book
		self.bbook = wx.Notebook( self.pbSplitter, -1,style=nb_style )
		# We don't assign the imagelist, we set it only. This way bbook does not delete the image list.
		self.bbook.SetImageList( self.il )
		self.bbook.Bind( wx.EVT_KEY_DOWN, self.OnKeyPressed )
		common.set_busy_info( "Loading the Binders module" )
		self.binder_control = binder_ui.binder_control( self.bbook, -1, self.account )
		self.bbook.AddPage( self.binder_control, "Binders" )
		self.contact_control = contact_ui.contact_control( self.bbook, self.account, True )
		self.bbook.AddPage( self.contact_control, "Contacts" )
		self.group_control = contact_ui.group_control( self.bbook, self.account, True )
		self.bbook.AddPage( self.group_control, "Groups" )
		self.trash_control = contact_ui.contact_control( self.bbook, self.account, True, True )
		self.bbook.AddPage( self.trash_control, "Trash" )
		self.rq_control = contact_ui.rq_control( self.bbook, self.account, True )
		self.bbook.AddPage( self.rq_control, "Pub. Requests" )
		self.pq_control = contact_ui.pq_control( self.bbook, self.account, True )
		self.bbook.AddPage( self.pq_control, "Pub. Queue" )		
		self.gcb_control = gcb_ui.gcb_control( self.bbook, -1, self.account )
		self.bbook.AddPage( self.gcb_control, "GCBs" )
		self.bbook.Show()
		if wx.Platform == '__WXMAC__':
			font = self.pbook.GetFont()
			font.SetPointSize( 9 )
			self.pbook.SetFont( font )
			font = self.bbook.GetFont()
			font.SetPointSize( 9 )
			self.bbook.SetFont( font )
			font = self.bbook.GetFont()
			font.SetPointSize( 9 )
			self.bbook.SetFont( font )
		# Done loading
		self.account_manager.set_account_loaded( account.id )
		common.clear_busy_info()
		self.zooming = True
		self.restore_splits()
		self.zooming = False
		self.Bind( wx.EVT_KEY_DOWN, self.OnKeyPressed )
		self.Show()

	def OnShowInspector(self,event):
		self.account_manager.showInspectorWindow()
		
	def OnShowScriptHelper(self,event):
		self.account_manager.showScriptHelperWindow()
		
	def icon_from_rex_object( self, object ):
		oclass = str( object.__class__ )
		if oclass == 'rex.publications.publication':
			if object.module.lower() == 'web':
				return self.folder_w_icon
			elif object.module.lower() == 'newsletter':
				return self.folder_n_icon
			elif object.module.lower() == 'email':
				return self.folder_e_icon
		if oclass == 'rex.forms.form':
			if object.module.lower() == 'survey':
				return self.form_icon
			elif object.module.lower() == 'referral':
				return self.promotion_icon
		elif oclass == 'rex.publications.issue':
			if object.publication.module.lower() == 'web':
				return self.issue_w_icon
			elif object.publication.module.lower() == 'newsletter':
				return self.issue_n_icon
			elif object.publication.module.lower() == 'email':
				return self.issue_e_icon
		elif oclass == 'rex.forms.survey':
			if object.form.module.lower() == 'survey':
				return self.survey_icon
			elif object.form.module.lower() == 'referral':
				return self.referral_icon
		elif oclass == 'rex.binders.binder':
			return self.binder_icon
		elif oclass == 'rex.binders.instance':
			return self.instance_icon
		elif oclass == 'rex.contacts.contact':
			return self.contact_icon
		elif oclass == 'rex.contacts.group':
			return self.group_icon
		return -1
		
	def icon_from_dav_object( self, object ):
		return -1
	
	def get_membership_editor( self, parent, kind ):
		if kind == 'contacts':
			return contact_ui.contact_control( parent, self.account, False )
		elif kind == 'groups':
			return contact_ui.group_control( parent, self.account, False )
		elif kind == 'processing queue':
			return contact_ui.pq_control( parent, self.account, False )
		return None

	def OnKeyPressed( self, event ):
		#common.dprint( "key press:", event )
		#common.dprint( "key press:", dir( event ) )
		#common.dprint( "event object", event.GetEventObject() )
		#~ print "zoom", event
		#print "Control:", event.ControlDown()
		#print "Alt:", event.AltDown()
		#print "Meta:", event.MetaDown()
		#~ print "key:", event.GetKeyCode()
		#control_down = event.ControlDown()
		#if wx.Platform == '__WXMAC__': control_down = event.MetaDown()
		if event.ControlDown():
			#elif ( key == ord('1') ) or ( key == ord('2') ) or ( key == ord('3') ) or ( key == ord('4') ):
			panel = 0
			if event.GetKeyCode() == ord('1'):
				panel = 1
			elif event.GetKeyCode() == ord('2'):
				panel = 2
			elif event.GetKeyCode() == ord('3'):
				panel = 3
			elif event.GetKeyCode() == ord('4'):
				panel = 4
			else:
				return
			self.OnZoom( panel )

	def OnZoom( self, panel ):
		if self.zoomed:
			if self.zoomedon == panel:
				self.zoom_out()
			else:
				self.zoom_out()
				self.zoom_in( panel )
		else:
			self.zoom_in( panel )

	def zoom_in( self, panel ):
		if self.zoomed and self.zoomedon == panel: return
		if panel == 1:
			pass
			# make sure ebook has at least one page
			# if self.ebook.GetPageCount() < 1: return
			# self.Splitter.Unsplit( self.pbSplitter )
			# self.eSplitter.Unsplit( self.bbook )
			# self.focus_on( self.ebook )
		elif panel == 2:
			# self.Splitter.Unsplit( self.eSplitter )
			self.pbSplitter.Unsplit( self.bbook )
			self.focus_on( self.pbook )
		elif panel == 3:
			# self.Splitter.Unsplit( self.eSplitter )
			self.pbSplitter.Unsplit( self.pbook )
			self.focus_on( self.bbook )
		else:
			return
		self.zoomedon = panel
		self.zoomed = True

	def zoom_out( self ):
		if not self.zoomed: return
		self.zooming = True
		self.restore_splits()
		self.zooming = False
		self.zoomed = False
		self.zoomedon = 0

	def restore_splits( self ):
		self.pbook.Show()
		self.bbook.Show()
		self.pbSplitter.SetMinimumPaneSize( 20 )
		self.pbSplitter.Unsplit()
		self.pbSplitter.SplitHorizontally( self.pbook, self.bbook, self.account.s1 )
		self.pbook.Show()
		self.bbook.Show()
		self.pbook.Refresh()
		self.bbook.Refresh()
		self.pbSplitter.Show()
		self.pbSplitter.Refresh()

	def focus_on( self, panel ):
		return
		if panel == self.ebook:
			self.ebook.SetFocus()
			if self.ebook.GetPageCount() < 1: return
			page = self.ebook.GetCurrentPage()
			if not page:
				common.dprint("focus_on: invalid returned page")
				return
			page.SetFocus()
 		if panel == self.pbook:
			self.pbook.SetFocus()
			page = self.ebook.GetCurrentPage()
			if not page:
				common.dprint("focus_on: invalid returned page")
				return
			common.dprint( page )
			page.SetFocus()
		elif panel == self.bbook:
			self.bbook.SetFocus()

	def OnSashChanged( self, event ):
		# Don't save when we are zoomed
		if self.zoomed or self.zooming: return
		if event.GetEventObject() == self.pbSplitter:
			self.account.s1 = event.GetSashPosition()
		self.account.save()

	def create_menu_items( self ):
		# Create the menu bar
		menubar = wx.MenuBar()
		self.menubar = menubar
		# The service menu
		menu = wx.Menu()
		menu.Append( IDM_PUBLISHER, "&Publisher Preferences", " Display the Publisher Preferences" )
		self.Bind( wx.EVT_MENU, self.OnPublisherPrefs, id=IDM_PUBLISHER )
		menu.Append( IDM_DISCONNECT, "&Disconnect", " Disconnect from this service" )
		self.Bind( wx.EVT_MENU, self.OnDisconnect, id=IDM_DISCONNECT )
		menubar.Append( menu, "&Account" )
		menu = wx.Menu()
		menu.Append( IDM_TRACER, "&Tracer", " Open the communication tracer" )
		self.Bind( wx.EVT_MENU, self.OnTrace, id=IDM_TRACER )
		menu.Append( IDM_BUILD, "&Build", " Open the Build App Window" )
		self.Bind( wx.EVT_MENU, self.OnBuild, id=IDM_BUILD )
		menu.Append( IDM_INSPECTOR, "&Object Inspector", " Display the object inspector" )
		self.Bind( wx.EVT_MENU, self.OnShowInspector, id=IDM_INSPECTOR )
		menu.Append( IDM_SCRIPT_HELPER, "&Script Helper", " Display the script helper" )
		self.Bind( wx.EVT_MENU, self.OnShowScriptHelper, id=IDM_SCRIPT_HELPER )
		menubar.Append( menu, "&Tools" )
		# All done
		self.SetMenuBar( menubar )

	def OnClose( self, event ):
		'''When closing the service frame, the account manager icon is updated and the
		service reference is cleared out.
		If the account manager's disconnect_account method returns a false, the closing is
		not performed.'''
		if self.account_manager.disconnect_account( self.account.id ):
			self.Destroy()

	def OnDisconnect( self, event ):
		self.OnClose( event )

	def OnTrace( self, event ):
		self.account_manager.OnTrace( event )
		
	def OnBuild( self, event ):
		if self.build_dialog is None:
			self.build_dialog = build_ui.build( self, self.account )
		self.build_dialog.Show()
		self.build_dialog.Raise()
		
	def OnPublisherPrefs( self, event ):
		dlg = publisher_prefs( self, self.account )
		common.metalic( dlg )
		dlg.ShowModal()
		dlg.Destroy()
		del( dlg )
	
class publisher_prefs( wx.Dialog ):
	def __init__( self, parent, account ):
		wx.Dialog.__init__( self, parent, -1, "Publisher Preferences", wx.DefaultPosition, wx.Size( 350, 450 )  )
		self.account = account
		# the main outer sizer
		sizer = wx.BoxSizer( wx.VERTICAL )
		# the publisher sizer
		pbox = wx.StaticBox(self, -1, "Publishing")
		psizer = wx.StaticBoxSizer( pbox, wx.VERTICAL )
		# Add the reply and cc address boxes
		self.publisher = wx.CheckBox( self, -1, "Enable Publishing"  )
		self.Bind( wx.EVT_CHECKBOX, self.update_ui, self.publisher )
		psizer.Add( self.publisher, 0, wx.EXPAND | wx.SOUTH, 10 )
		self.account_email_label = wx.StaticText( self, -1, "Default Email" )
		psizer.Add( self.account_email_label, 0, wx.EXPAND | wx.WEST, 20 )
		self.account_email = wx.TextCtrl( self, -1 )
		psizer.Add( self.account_email, 0, wx.EXPAND | wx.WEST, 20 )
		self.at_label = wx.StaticText( self, -1, "Run at" )
		psizer.Add( self.at_label, 0, wx.EXPAND | wx.WEST, 20 )
		tsizer = wx.BoxSizer( wx.HORIZONTAL )
		self.at = masked.TimeCtrl( self, -1, name="at", display_seconds=False )
		h = self.at.GetSize().height
		self.tspin = wx.SpinButton( self, -1, wx.DefaultPosition, (-1,h), wx.SP_VERTICAL )
		self.at.BindSpinButton( self.tspin )
		tsizer.Add( self.at, 1, wx.EXPAND )
		tsizer.Add( self.tspin, 0, wx.EXPAND )
		psizer.Add( tsizer, 0, wx.EXPAND | wx.WEST, 20 )
		self.dated = wx.CheckBox( self, -1, "Dated"  )
		psizer.Add( self.dated, 0, wx.EXPAND | wx.WEST, 20 )
		self.timed = wx.CheckBox( self, -1, "Timed"  )
		psizer.Add( self.timed, 0, wx.EXPAND | wx.WEST, 20 )
		self.recurring = wx.CheckBox( self, -1, "Recurring"  )
		psizer.Add( self.recurring, 0, wx.EXPAND | wx.WEST, 20 )
		# add the publishing sizer to the main sizer
		sizer.Add( psizer, 0, wx.EXPAND )
		# the publisher sizer
		bbox = wx.StaticBox(self, -1, "Bounce Management")
		bsizer = wx.StaticBoxSizer( bbox, wx.VERTICAL )
		# Add the bounce addresses and stuff
		self.bouncer = wx.CheckBox( self, -1, "Enable Bounce Management"  )
		self.Bind( wx.EVT_CHECKBOX, self.update_ui, self.bouncer )
		bsizer.Add( self.bouncer, 0, wx.EXPAND | wx.SOUTH, 10 )
		self.bounce_email_label = wx.StaticText( self, -1, "Bounce Email" )
		bsizer.Add( self.bounce_email_label, 0, wx.EXPAND | wx.WEST, 20 )
		self.bounce_email = wx.TextCtrl( self, -1 )
		bsizer.Add( self.bounce_email, 0, wx.EXPAND | wx.WEST, 20 )
		self.bounce_group_label = wx.StaticText( self, -1, "Bounce Group" )
		bsizer.Add( self.bounce_group_label, 0, wx.EXPAND | wx.WEST, 20 )
		self.bounce_group = wx.TextCtrl( self, -1 )
		bsizer.Add( self.bounce_group, 0, wx.EXPAND | wx.WEST, 20 )
		# add the bounce sizer to the main sizer
		sizer.Add( bsizer, 0, wx.EXPAND )
		# Add the buttons
		self.button_sizer = wx.BoxSizer( wx.HORIZONTAL )
		btn = wx.Button( self, wx.ID_CANCEL, "&Cancel" )
		btn.SetDefault()
		self.button_sizer.Add( (10,0), 0, 1 )
		self.button_sizer.Add( btn, 1, 0 )
		self.button_sizer.Add( (10,0), 0, 1 )
		btn = wx.Button( self, -1, "&Apply" )
		btn.Bind( wx.EVT_BUTTON, self.OnApply )
		self.button_sizer.Add( btn, 1, 0 )
		self.button_sizer.Add( (10,0), 0, 1 )
		self.sizer = wx.BoxSizer( wx.VERTICAL )
		self.sizer.Add( sizer, 1, wx.EXPAND | wx.NORTH | wx.SOUTH | wx.EAST | wx.WEST, 10 )
		self.sizer.Add( self.button_sizer, 0, wx.EXPAND | wx.ALIGN_CENTER | wx.SOUTH, 20 )
		self.SetSizer( self.sizer )
		self.SetAutoLayout( 1 )
		# Windows needs this call
		self.Layout()
		self.load_prefs()

	def load_prefs( self ):
		common.set_busy_info("Loading publishing preferences...")
		cur = wx.BusyCursor()
		pnode = None
		try:
			xmlstring = self.account.execute( 'base', "get_publisher_prefs")
			#xmlstring = "<publisher_prefs enabled='yes' at='7:30 am' dated='yes' timed='no' recurring='yes' />"
			xmlstring = common.uni2str( xmlstring )
			pdom 	= minidom.parseString( xmlstring )
			pnode	= pdom.firstChild
		except:
			common.show_error("Failed to load publisher preferences")
		del cur
		common.clear_busy_info()
		#print pnode.attributes
		publisher	= pnode.attributes['enabled'].value
		account_email=pnode.attributes['account_email'].value
		at			= pnode.attributes['at'].value
		dated		= pnode.attributes['dated'].value
		timed		= pnode.attributes['timed'].value
		recurring	= pnode.attributes['recurring'].value
		bouncer		= pnode.attributes['bouncer'].value
		bounce_email= pnode.attributes['bounce_email'].value
		bounce_group= pnode.attributes['bounce_group'].value
		# create a time
		import time
		from wx import DateTime
		dtAt = DateTime.Now()
		try:
			intime = time.strptime(at, "%I:%M %p")
			dtAt.SetHour( intime.tm_hour )
			dtAt.SetMinute( intime.tm_min )
		except:
			common.dprint("Failed to parse publishing time")
		at = dtAt
		# update the controls
		self.publisher.SetValue( publisher == 'yes' )
		self.at.SetValue( at )
		self.dated.SetValue( dated == 'yes' )
		self.timed.SetValue( timed == 'yes' )
		self.recurring.SetValue( recurring == 'yes' )
		self.bouncer.SetValue( bouncer == 'yes' )
		self.account_email.SetValue( account_email )
		self.bounce_email.SetValue( bounce_email )
		self.bounce_group.SetValue( bounce_group )
		self.update_ui()
	
	def update_ui( self, event = None ):
		common.dprint("Update UI Pub ", self.publisher.GetValue() )
		common.dprint("Update UI Bnc ", self.bouncer.GetValue() )
		self.account_email_label.Enable(  self.publisher.GetValue() )
		self.account_email.Enable(  self.publisher.GetValue() )
		self.at_label.Enable(  self.publisher.GetValue() )
		self.at.Enable(  self.publisher.GetValue() )
		self.tspin.Enable(  self.publisher.GetValue() )
		self.dated.Enable(  self.publisher.GetValue() )
		self.timed.Enable(  self.publisher.GetValue() )
		self.recurring.Enable(  self.publisher.GetValue() )
		self.bounce_email_label.Enable(  self.bouncer.GetValue() )
		self.bounce_email.Enable(  self.bouncer.GetValue() )
		self.bounce_group_label.Enable(  self.bouncer.GetValue() )
		self.bounce_group.Enable(  self.bouncer.GetValue() )
		
	def OnApply( self, event ):
		common.dprint('Apply publishing properties')
		enabled = 'no'
		if self.publisher.GetValue(): enabled = 'yes'
		account_email = self.account_email.GetValue()
		dated = 'no'
		if self.dated.GetValue(): dated = 'yes'
		timed = 'no'
		if self.timed.GetValue(): timed = 'yes'
		recurring = 'no'
		if self.recurring.GetValue(): recurring = 'yes'
		at = self.at.GetValue()
		bouncer = 'no'
		if self.bouncer.GetValue(): bouncer = 'yes'
		bounce_email = self.bounce_email.GetValue()
		bounce_group = self.bounce_group.GetValue()
		dom = "<publishing_prefs enabled='%s' account_email='%s' at='%s' dated='%s' timed='%s' recurring='%s' bouncer='%s' bounce_email='%s' bounce_group='%s' />" % ( enabled, account_email, at, dated, timed, recurring, bouncer, bounce_email, bounce_group )
		common.dprint("Sending ", dom )
		res = self.account.execute( 'base', "set_publisher_prefs", DOM=dom)
		if not res:
			wx.MessageBox( "Failed to apply publisher preferences", "Applying Preferences", wx.OK )
			return
		self.Close()